package com.pk.center.sign.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.pk.center.sign.config.esignConfig.cn.tsign.hz.comm.EsignHttpResponse;
import com.pk.center.sign.config.esignConfig.cn.tsign.hz.exception.EsignDemoException;
import com.pk.center.sign.dto.CustInfo;
import com.pk.center.sign.dto.CustomerDto;
import com.pk.center.sign.dto.SignInfo;
import com.pk.center.sign.service.CountryService;
import com.pk.center.sign.service.CustomerService;
import com.wl.center.common.result.Result;
import com.wl.center.model.sign.Customer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.pk.center.sign.config.esignConfig.fileAndTemplate.TemplateDemo.createByDocTemplate;
import static com.pk.center.sign.config.esignConfig.sign.SignDemo.*;
import static com.wl.center.common.result.ResultCodeEnum.*;

@Slf4j
@RestController
@Api(tags = "电子签名")
@RequestMapping("/esign")
@CrossOrigin
public class EsignController {

    private static Integer SIGN_STATUS_COMPLETED = 0;//已签署
    private static Integer SIGN_STATUS_SIGNING = 1;//已发起未签署
    private static Integer SIGN_STATUS_NOT_INITIATE = 2;//未发起

    @Autowired
    private CustomerService customerService;

    @Autowired
    private CountryService countryService;

    //1.发起签约
    @ApiOperation(value = "发起签约")
    @PostMapping("/send-sign")
    public Result sendSign(@RequestBody CustomerDto customerDto) throws EsignDemoException {
        log.info("customerDto---{}",customerDto);
        //填充数据生产模板
        Gson gson = new Gson();
        System.out.println(customerDto.toString());
        EsignHttpResponse createByDocTemplate = createByDocTemplate(customerDto);
        JsonObject createByDocTemplateObject = gson.fromJson(createByDocTemplate.getBody(), JsonObject.class);
        String fileId = createByDocTemplateObject.getAsJsonObject("data").get("fileId").getAsString();
        //String fileDownloadUrl = createByDocTemplateObject.getAsJsonObject("data").get("fileDownloadUrl").getAsString();

        //先获取当前用户的信息
        Customer customer = customerService.getById(customerDto.getCustomerId());

        if (customer.getSignFlowId() != null) {//signFlowId不为空说明已签署过
            return Result.build(SUCCESS.getCode(), "请勿反复发送签约");
        }

        //发起签约
        EsignHttpResponse createByFile = createByFile(fileId, customerDto.getTel());
        JSONObject createByFileJsonObject = JSONObject.parseObject(createByFile.getBody());
        String signFlowId = createByFileJsonObject.getJSONObject("data").getString("signFlowId");

        //将流程单号存到数据库表里以便后续查询
        customer.setSignFlowId(signFlowId);

        customer.setSignStatus(SIGN_STATUS_SIGNING);
        boolean flag = customerService.updateById(customer);

        if (flag)
            return Result.ok();
        else
            return Result.fail();

    }

    //2.获取数据库已有信息，填充发起签约页面
    @ApiOperation(value = "跳转签约页面,自动填充信息")
    @GetMapping("/get-info/{customerId}")
    public Result<SignInfo> getInfo(@PathVariable Long customerId) {
        Customer customer = customerService.getById(customerId);
        SignInfo signInfo = new SignInfo();
        BeanUtils.copyProperties(customer, signInfo);
        //获取国家id
        String toCountry = signInfo.getToCountry();
        Long toCountryId = Long.parseLong(toCountry);
        //查询国家名
        String countryName = countryService.getById(toCountryId).getName();
        signInfo.setToCountry(countryName);
        return Result.ok(signInfo);
    }

    //3.查询签署状态
    @ApiOperation(value = "查询签署状态")
    @GetMapping("/check-status/{customerId}")
    public Result<List<CustInfo>> checkStatus(@PathVariable Long customerId) throws EsignDemoException {

        Customer customer = customerService.getById(customerId);
        Integer signStatus;
        if (customer == null) {
            return Result.build(SUCCESS.getCode(), "该用户不存在");
        }
        String signFlowId = customer.getSignFlowId();
        if (signFlowId == null) {
            return Result.build(SUCCESS.getCode(), "未发起签约,请先发起签约");
        }
        EsignHttpResponse response = signFlowDetail(signFlowId);
        JSONObject res = JSONObject.parseObject(response.getBody());
        String signFlowStatus = res.getJSONObject("data").getString("signFlowStatus");

        if (signFlowStatus.equals(SIGN_FLOW_STATUS_FINISHED.getCode().toString())) {
            //对方已签署
            signStatus = SIGN_STATUS_COMPLETED;
        } else if (signFlowStatus.equals(SIGN_FLOW_STATUS_SIGNING.getCode().toString())) {
            //对方签署中(已发起未签署)
            signStatus = SIGN_STATUS_SIGNING;
        } else {
            //未发起
            signStatus = SIGN_STATUS_NOT_INITIATE;
        }
        customer.setSignStatus(signStatus);
        customerService.updateById(customer);
        CustInfo custInfo = new CustInfo();
        BeanUtils.copyProperties(customer, custInfo);
        List<CustInfo> custInfoList = new ArrayList<>();
        custInfoList.add(custInfo);
        return Result.ok(custInfoList);
    }

    //4.下载已签署文件
    @ApiOperation(value = "获取已签署文件下载链接")
    @GetMapping("/download-file/{customerId}")
    public Result downloadFile(@PathVariable Integer customerId) throws EsignDemoException {

        Customer customer = customerService.getById(customerId);
        if (customer == null) {
            return Result.build(SUCCESS.getCode(), "该用户不存在");
        }
        String signFlowId = customer.getSignFlowId();
        if (signFlowId == null) {
            return Result.build(SUCCESS.getCode(), "未发起签约,请先发起签约");
        }
        //从返回的JSON字符串中获取下载地址
        //签署成功流程单号示例："29ec93acc4384a6082246feeb0988fca
        EsignHttpResponse response = fileDownloadUrl(signFlowId);
        JSONObject res = JSONObject.parseObject(response.getBody());
        Integer code = (Integer) res.get("code");

        EsignHttpResponse response1 = signFlowDetail(signFlowId);
        JSONObject res1 = JSONObject.parseObject(response1.getBody());
        String signFlowStatus = res1.getJSONObject("data").getString("signFlowStatus");
        Integer signStatus;
        if (signFlowStatus.equals(SIGN_FLOW_STATUS_FINISHED.getCode().toString())) {
            //对方已签署
            signStatus = SIGN_STATUS_COMPLETED;
            customer.setSignStatus(signStatus);
            customerService.updateById(customer);
        } else if (signFlowStatus.equals(SIGN_FLOW_STATUS_SIGNING.getCode().toString())) {
            //对方签署中(已发起未签署)
            signStatus = SIGN_STATUS_SIGNING;
            customer.setSignStatus(signStatus);
            customerService.updateById(customer);
        }

        if (code != 0) {
            return Result.build(SUCCESS.getCode(),"对方还未完成签署,无法下载文件");
        } else {
            JSONObject f = res.getJSONObject("data");
            JSONArray filesArray = f.getJSONArray("files");
            String downloadUrl = filesArray.getJSONObject(0).getString("downloadUrl");
            //System.out.println(downloadUrl); // 打印下载链接
            Map<String, String> map = new HashMap<>();
            map.put("link", downloadUrl);
            return Result.ok(map);
        }
    }

    //5.按状态分页查询所有客户信息
    //flag---1.全部客户;2.已发起（未签署）的客户;3.已签约的客户
    @ApiOperation(value = "按状态分页查询所有客户信息")
    @GetMapping("/get/by-flag/{sellerId}/{currentPage}/{rows}/{flag}")
    public Result getCusByStatus(@PathVariable Integer sellerId,
                                 @PathVariable long currentPage,
                                 @PathVariable long rows,
                                 @PathVariable Integer flag
    ) {
        Page<Customer> page = new Page<>(currentPage,rows);
        List<CustInfo> custInfoList = new ArrayList<>();
        CustInfo custInfo = new CustInfo();//创建一个中间类对象CustInfo
        //构建条件，用条件构造器
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        if(!StringUtils.isEmpty(sellerId)) {
            queryWrapper.eq(Customer::getSellerId,sellerId);
        }
        //查询已发起签约的和签约完成的(sign_status为0或1),即查询所有
        if(flag == 1){
            //已发起的未签署的+已签署的客户
        queryWrapper.ne(Customer::getSignStatus,SIGN_STATUS_NOT_INITIATE);
        }else if(flag == 2){
            //已发起但未签署的客户
            queryWrapper.eq(Customer::getSignStatus,SIGN_STATUS_SIGNING);
        }else{
            //已签署的客户
            queryWrapper.eq(Customer::getSignStatus,SIGN_STATUS_COMPLETED);
        }
        //将查询到的数据按创建时间的由早到晚排列，升序
        queryWrapper.orderByAsc(Customer::getCreateTime);
        //调用方法实现分页查询
        IPage<Customer> pageCustomer = customerService.page(page, queryWrapper);//通过查customer表把一些基本信息取出
        List<Customer> customerList = pageCustomer.getRecords();//将这些基本信息放到customerList
        IPage<CustInfo> page1 = new Page<>();
        for (Customer customer:customerList) {
            custInfo= new CustInfo();
            BeanUtils.copyProperties(customer, custInfo);
            custInfoList.add(custInfo);
        }
        page1.setPages(pageCustomer.getPages());
        page1.setCurrent(pageCustomer.getCurrent());
        page1.setSize(pageCustomer.getSize());
        page1.setTotal(pageCustomer.getTotal());
        page1.setRecords(custInfoList);
        //返回结果
        return Result.ok(page1);
    }

    //6.刷新签署状态(检查未签署的客户是否已完成签署)
    @ApiOperation(value = "刷新签署状态")
    @PutMapping("/refresh-status/{sellerId}/{currentPage}/{rows}")
    public Result refreshStatus(@PathVariable Integer sellerId,
                                @PathVariable long currentPage,
                                @PathVariable long rows

    ) throws EsignDemoException {
        Page<Customer> page = new Page<>(currentPage,rows);
        List<CustInfo> custInfoList = new ArrayList<>();
        CustInfo custInfo = new CustInfo();//创建一个中间类对象CustInfo
        //构建条件，用条件构造器
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        if(!StringUtils.isEmpty(sellerId)) {
            queryWrapper.eq(Customer::getSellerId,sellerId);
        }
        //查询已发起签约的和签约完成的(sign_status为0或1),即查询所有

        //已发起但未签署的客户
        queryWrapper.eq(Customer::getSignStatus,SIGN_STATUS_SIGNING);

        //将查询到的数据按创建时间的由早到晚排列，升序
        queryWrapper.orderByAsc(Customer::getCreateTime);
        //调用方法实现分页查询
        IPage<Customer> pageCustomer = customerService.page(page, queryWrapper);//通过查customer表把一些基本信息取出
        List<Customer> customerList = pageCustomer.getRecords();//将这些基本信息放到customerList
        IPage<CustInfo> page1 = new Page<>();
        for (Customer customer:customerList) {
            //查询签署状态
            String signFlowId = customer.getSignFlowId();
            EsignHttpResponse response = signFlowDetail(signFlowId);
            JSONObject res = JSONObject.parseObject(response.getBody());
            String signFlowStatus = res.getJSONObject("data").getString("signFlowStatus");
            if (signFlowStatus.equals(SIGN_FLOW_STATUS_FINISHED.getCode().toString())) {
                //对方已签
                customer.setSignStatus(SIGN_STATUS_COMPLETED);
                customerService.updateById(customer);
            }
            if(customer.getSignStatus()!=SIGN_STATUS_COMPLETED){
                custInfo= new CustInfo();
                BeanUtils.copyProperties(customer, custInfo);
                custInfoList.add(custInfo);
            }
        }
        page1.setPages(pageCustomer.getPages());
        page1.setCurrent(pageCustomer.getCurrent());
        page1.setSize(pageCustomer.getSize());
        page1.setTotal(custInfoList.size());
        page1.setRecords(custInfoList);
        //返回结果
        return Result.ok(page1);
    }
}
